/***************************************************************************************
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
*
* NEMU is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*          http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*
* See the Mulan PSL v2 for more details.
***************************************************************************************/

#include <isa.h>
#include "local-include/reg.h"

const char *regs[] = {
  "$0", "ra", "sp", "gp", "tp", "t0", "t1", "t2",
  "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5",
  "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7",
  "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6"
};
const char *csrs[] = {
  "mstatus", "mtvec", "mepc", "mcause", 
};
const word_t csrindexs[] = {
  0x300, 0x305, 0x341, 0x342, 
};
word_t cpu_csr[4]={0xa00001800,0,0,0};

void isa_reg_display() {
    for(int i=0;i<32;i++)
    {
        printf("%-3s:0x%016lx\n",*(regs+i),cpu.gpr[i]); 
    }
}

word_t isa_reg_str2val(const char *s, bool *success) {
  for(int i=0;i<32;i++)
  {
    if(strcmp(s,regs[i])==0){
      *success=true;
      return cpu.gpr[i];
    }
  }
  for(int i=0;i<4;i++)
  {
    if(strcmp(s,csrs[i])==0){
      *success=true;
      return cpu_csr[i];
    }
  }
  if(strcmp(s,"pc")==0)
  {
    *success=true;
    return cpu.pc;
  }
  *success=false;
  return 0;
}
word_t csrindex(char* s)
{
  for(int i=0;i<4;i++)
  {
    if(strcmp(s,csrs[i])==0)
      return csrindexs[i];
  }
	return -1;
}

void csrW(word_t csr, word_t data)
{
	int i=-1;
	/*printf("csr=%lx",csr);*/
	switch(csr)
	{
		case 0x300:
			i=0;
			break;
		case 0x305:
			i=1;
			break;
		case 0x341:
			i=2;
			break;
		case 0x342:
			i=3;
			break;
		default:
			Assert(0,"wrong csr!\n");
	}
	cpu_csr[i]=data;
}

word_t csrR(word_t csr)
{
	int i=-1;
	/*printf("csr=%lx",csr);*/
	switch(csr)
	{
		case 0x300:
			i=0;
			break;
		case 0x305:
			i=1;
			break;
		case 0x341:
			i=2;
			break;
		case 0x342:
			i=3;
			break;
		default:
			Assert(0,"wrong csr!\n");
	}
	return cpu_csr[i];
}
